home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 May / EnigmA AMIGA RUN 18 (1997)(G.R. Edizioni)(IT)[!][issue 1997-05][EAR-CD II].iso / earcd / util / sys / msys_1_2.lha / Src / requestchoice.c < prev   
C/C++ Source or Header  |  1996-12-27  |  9KB  |  282 lines

  1. /*
  2. **    requestchoice.c - request information from user
  3. **    $VER: requestchoice.c 42.2 (27.12.96)
  4. **    Copyright © 1996 Michal Letowski
  5. **
  6. **    42.1 (4.7.96) - initial version
  7. **    42.2 (27.12.96)
  8. **        ! an invisible window was left on public screens - fixed
  9. **        + now reacts to break signal
  10. */
  11.  
  12. #define __USE_SYSBASE
  13.  
  14. #include <exec/types.h>
  15. #include <exec/execbase.h>
  16. #include <exec/libraries.h>
  17. #include <exec/memory.h>
  18. #include <dos/dos.h>
  19. #include <dos/rdargs.h>
  20. #include <intuition/intuition.h>
  21. #include <utility/tagitem.h>
  22. #include <support/types.h>
  23. #include <support/exec.h>
  24. #include <support/dos.h>
  25.  
  26. #include <string.h>
  27.  
  28. #include <proto/exec.h>
  29. #include <proto/dos.h>
  30. #include <proto/intuition.h>
  31.  
  32. #include "requestchoice.rev.h"
  33.  
  34.  
  35. /*
  36. **    Constants
  37. */
  38. #define DOS_NAME                    "dos.library"
  39. #define DOS_VERN                    37L
  40. #define INT_NAME                    "intuition.library"
  41. #define INT_VERN                    37L
  42.  
  43. #define TEMPLATE                    "TITLE/A,BODY/A,GADGETS/A/M,PUBSCREEN/K,TIMEOUT/K/N"
  44.  
  45. #define DELAY_AMOUNT            10
  46.  
  47. #define MICROS_PER_SECOND    1000000
  48.  
  49. #define MicroTime(s,m)        (CurrentTime(&(s),&(m)), (s)*MICROS_PER_SECOND+(m))
  50.  
  51.  
  52. /*
  53. **    Private structures
  54. */
  55. struct Options
  56. {
  57.     STRPTR  opt_Title;                                                        /* TITLE/A */
  58.     STRPTR  opt_Body;                                                            /* BODY/A */
  59.     STRPTR *opt_Gadgets;                                                    /* GADGETS/A */
  60.     STRPTR  opt_PubScreen;                                                /* PUBSCREEN/K */
  61.     LONG   *opt_Timeout;                                                    /* TIMEOUT/K/N */
  62. };    /* Options */
  63.  
  64.  
  65. /*
  66. **    Global data
  67. */
  68. STATIC CONST TEXT VersionString[]=
  69.     VERSION(PROG_NAME,PROG_VERSION,PROG_REVISION,PROG_DATE);
  70.  
  71.  
  72. /*
  73. **    Level 1 private functions prototypes
  74. */
  75. STATIC STRPTR CreateGadgetString(STRPTR *gadgets);
  76.  
  77.  
  78. /*
  79. **    Public functions
  80. */
  81. /****** C/RequestChoice *****************************************************
  82. *
  83. *   NAME
  84. *       RequestChoice -- create and handle a decision requester. (V39)
  85. *
  86. *   SYNOPSIS
  87. *       RequestChoice Title Body Button1 Button2 ... ButtonN
  88. *       [PUBSCREEN=PubScreenName] [TIMEOUT=TimeoutValue]
  89. *
  90. *   TEMPLATE
  91. *       RequestChoice "TITLE/A,BODY/A,GADGETS/A/M,PUBSCREEN/K,TIMEOUT/K/N"
  92. *
  93. *   FUNCTION
  94. *       Opens a requester window on a given public screen with a choice of
  95. *       one or more buttons. Chosen button number is printed. Buttons are
  96. *       numbered from left to right, with the leftmost button being number
  97. *       1. The rightmost button has a number 0 assigned to it. If there is
  98. *       only one button, it is treated as 0.
  99. *       A requester can cancel itself after a specified amount of time. In
  100. *       such case 0 is returned and printed.
  101. *
  102. *   INPUTS
  103. *       TITLE     - a title of the requester window.
  104. *       BODY      - a text to appear inside requester window.
  105. *       GADGETS   - one or more strings representing button texts.
  106. *       PUBSCREEN - name of the public screen the requester should appear on.
  107. *                   If the screen is unavailable, the requester will appear
  108. *                   on default public screen - in most cases Workbench.
  109. *       TIMEOUT   - a value given in seconds after which a requester will
  110. *                   cancel itself.
  111. *
  112. *   RESULT
  113. *       RETURN_FAIL  - if 'dos.library' or 'intuition.library' couldn't be
  114. *                      opened.
  115. *       RETURN_ERROR - if command line arguments couldn't be processed or
  116. *                      there wasn't enough memory.
  117. *       RETURN_WARN  - if a given public screen couldn't be found or there
  118. *                      was a problem building a requster.
  119. *       RETURN_OK    - if everything went OK.
  120. *
  121. *   EXAMPLE
  122. *       RequestChoice "Test1" "Choose OK or Cancel" "OK" "Cancel"
  123. *           ; Puts a requester with 'Test' title, 'Choose OK or Cancel' text
  124. *           ; inside requester window and two buttons named 'OK' and
  125. *           ; 'Cancel'. If a user presses 'OK', '1' will be printed. If a
  126. *           ; user presses 'Cancel', '0' will be printed.
  127. *       RequestChoice "Test2" "Select number" "1" "2" "3" "4" "5"
  128. *                     PUBSCREEN="DOPUS.1" TIMEOUT=10
  129. *           ; Puts a requester with five choices buttons on Directory Opus'
  130. *           ; screen. If a user doesn't press any button within ten seconds,
  131. *           ; a requester will cancel itself and '0' will be printed.
  132. *
  133. *   NOTES
  134. *       This version of the command differs from original in that it will
  135. *       create a requester even if a given public screen doesn't exist.
  136. *
  137. *   BUGS
  138. *       Timeouts are precise to about 1/3 of a second.
  139. *
  140. *   SEE ALSO
  141. *       intuition.library/EasyRequestArgs().
  142. *
  143. *****************************************************************************
  144. *
  145. */
  146. LONG RequestChoice(VOID)
  147. {
  148.     STATIC CONST struct TagItem WinTags[]=
  149.     {
  150.         {WA_Left,                        0},
  151.         {WA_Top,                        0},
  152.         {WA_Width,                    16},
  153.         {WA_Height,                    16},
  154.         {WA_Backdrop,                TRUE},
  155.         {WA_Borderless,            TRUE},
  156.         {WA_NoCareRefresh,    TRUE},
  157.         {WA_RMBTrap,                TRUE},
  158.         {TAG_DONE,                    0}
  159.     };    /* WinTags */
  160.  
  161.     struct ExecBase *SysBase=INITSYSBASE;
  162.     struct Library *DOSBase;
  163.     struct Library *IntuitionBase;
  164.  
  165.     struct Options Opts;
  166.     struct EasyStruct ES;
  167.     struct RDArgs *Args;
  168.     struct Window *Win=NULL,*Req;
  169.     STRPTR GadBuf;
  170.     ULONG Secs,Mics,Time;
  171.     LONG ReqRes,RC=RETURN_FAIL;
  172.     
  173.     /* Open DOS */
  174.     unless(DOSBase=OpenLibrary(DOS_NAME,DOS_VERN))
  175.         throw2(SetResult2(ERROR_INVALID_RESIDENT_LIBRARY),    NO_DOS);
  176.  
  177.     /* Open Intuition */
  178.     unless(IntuitionBase=OpenLibrary(INT_NAME,INT_VERN))
  179.         throw2(CauseIoErr(ERROR_INVALID_RESIDENT_LIBRARY,PROG_NAME),    NO_INT);
  180.  
  181.     RC=RETURN_ERROR;                                                            /* Working a bit... */
  182.  
  183.     /* Read arguments */
  184.     clear(&Opts);                                                                    /* Clear out buffer */
  185.     unless(Args=ReadArgs(TEMPLATE,(LONG *)&Opts,NULL))
  186.         throw2(PrintFault(IoErr(),PROG_NAME),    NO_ARGS);
  187.  
  188.     /* Merge gadgets strings into one big string */
  189.     unless(GadBuf=CreateGadgetString(Opts.opt_Gadgets))
  190.         throw2(PrintFault(IoErr(),PROG_NAME),    NO_MEM);
  191.  
  192.     RC=RETURN_OK;                                                                    /* Everything seems to be ok... */
  193.  
  194.     /* Prepare EasyRequest structure */
  195.     ES.es_StructSize=sizeof(ES);
  196.     ES.es_Flags=0;
  197.     ES.es_Title=Opts.opt_Title;
  198.     ES.es_TextFormat="%s";
  199.     ES.es_GadgetFormat="%s";
  200.  
  201.     /* If public screen given, create a dummy window on it */
  202.     if(Opts.opt_PubScreen)
  203.         unless(Win=OpenWindowTags(NULL,    WA_PubScreenName,    Opts.opt_PubScreen,
  204.                                                                         TAG_MORE,                    WinTags))
  205.             RC=RETURN_WARN;                                                        /* Warning if no public screen */
  206.  
  207.     /* Create requester */
  208.     Req=BuildEasyRequest(Win,&ES,NULL,Opts.opt_Body,GadBuf);
  209.     if(Win)
  210.         CloseWindow(Win);                                                        /* Close window (if any) */
  211.  
  212.     /* Handle requester */
  213.     if((ULONG)Req>1)                                                            /* Created successfully... */
  214.     {
  215.         /* Handle requester */
  216.         if(Opts.opt_Timeout)
  217.             Time=MicroTime(Secs,Mics)+
  218.                         clamp(*Opts.opt_Timeout,0,MAXINT/MICROS_PER_SECOND)*MICROS_PER_SECOND;
  219.         forever
  220.         {
  221.             ReqRes=SysReqHandler(Req,NULL,FALSE);            /* Handle requester input */
  222.             if(ReqRes>=0 || CheckSignal(SIGBREAKF_CTRL_C))
  223.                 break;                                                                    /* Out of loop if gadget chosen or break */
  224.             if(Opts.opt_Timeout && MicroTime(Secs,Mics)>=Time)
  225.                 break;                                                                    /* Out of loop if timeout */
  226.             Delay(DELAY_AMOUNT);                                            /* Wait a moment */
  227.         }    /* forever */
  228.         FreeSysRequest(Req);                                                /* Remove requester */
  229.     }    /* if */
  230.     else                                                                                    /* Created successfully */
  231.     {
  232.         ReqRes=(LONG)Req;                                                        /* Set result */
  233.         RC=RETURN_WARN;                                                            /* So warn user */
  234.     }    /* else */
  235.  
  236.     /* Print result */
  237.     Printf("%ld\n",ReqRes<0 ? 0 : ReqRes);                /* 0 if timeout, else gadget code  */
  238.  
  239.     /* Exceptions */
  240.     catch(BAD_ARGS,    );
  241.     catch(NO_MEM,        FreeVec(GadBuf));
  242.     catch(NO_ARGS,    FreeArgs(Args));
  243.     catch(NO_INT,        CloseLibrary(IntuitionBase));
  244.     catch(NO_DOS,        CloseLibrary(DOSBase));
  245.     return(RC);
  246. }    /* RequestChoice */
  247.  
  248.  
  249. /*
  250. **    Level 1 private functions
  251. */
  252. STATIC STRPTR CreateGadgetString(STRPTR *gadgets)
  253. {
  254.     struct ExecBase *SysBase=INITSYSBASE;
  255.  
  256.     STRPTR *ArgPtr,CurArg,GadBuf,CurBuf;
  257.     LONG GadLen=0;
  258.     
  259.     /* Process all gadgets strings */
  260.     ArgPtr=gadgets;
  261.     while(CurArg=*ArgPtr++)                                                    /* For each gadget string */
  262.         GadLen+=strlen(CurArg)+1;                                            /* Add length of current string */
  263.     GadLen++;                                                                                /* NULL terminator, GadLen>0 */
  264.  
  265.     /* Allocate memory for gadgets string */
  266.     if(GadBuf=AllocVec(GadLen,MEMF_PUBCLR))                    /* Try to allocate memory for merged strings */
  267.     {                                                                                                /* OK - merge strings */
  268.         CurBuf=GadBuf;
  269.         ArgPtr=gadgets;                                                                /* First gadgets string */
  270.         while(CurArg=*ArgPtr++)                                                /* For each gadget string */
  271.         {
  272.             GadLen=strlen(CurArg);                                            /* Find length of gadget string */
  273.             MemCopy(CurBuf,CurArg,GadLen);                            /* Copy gadget string to buffer */
  274.             CurBuf+=GadLen;                                                            /* Advance buffer */
  275.             *CurBuf++='|';                                                            /* Add separator */
  276.         }
  277.         *(CurBuf-1)='\0';                                                            /* Change last '|' into NULL */
  278.     }
  279.  
  280.     return(GadBuf);
  281. }    /* CreateGadgetString */
  282.